package com.base.self.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.base.comm.CommUrls;
import com.base.exception.BaseException;
import com.base.mapper.voipmapper.SubscribersMapper;
import com.base.mapper.voipmapper.UserAuthInfoMapper;
import com.base.po.voip.Subscribers;
import com.base.po.voip.UserAuthInfo;
import com.base.result.PageUtils;
import com.base.result.ResponseResult;
import com.base.result.ResponseResultUtils;
import com.base.self.dto.ptTeam.*;
import com.base.self.entity.Commodity;
import com.base.self.entity.PtCurrent;
import com.base.self.entity.PtSuccess;
import com.base.self.entity.SelfOrder;
import com.base.self.mapper.CommodityMapper;
import com.base.self.mapper.PtCurrentMapper;
import com.base.self.service.IPtCurrentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.base.self.service.IPtSuccessService;
import com.base.self.service.IPtgoldbeanService;
import com.base.self.service.ISelfOrderService;
import com.base.utils.DateUtil;
import com.base.utils.Redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.base.utils.StringUtils;

import java.util.*;

@Slf4j
@Service
@Transactional
public class PtCurrentServiceImpl extends ServiceImpl<PtCurrentMapper, PtCurrent> implements IPtCurrentService {
    private final IPtSuccessService ptSuccessService;
    private final RedisUtil redisUtil;
    private final CommodityMapper commodityMapper;
    private final SubscribersMapper subscribersMapper;
    private final UserAuthInfoMapper userAuthInfoMapper;
    private final ISelfOrderService iSelfOrderService;
    private final IPtgoldbeanService ptgoldbeanService;

    public PtCurrentServiceImpl(IPtSuccessService ptSuccessService,IPtgoldbeanService ptgoldbeanService, RedisUtil redisUtil, CommodityMapper commodityMapper, SubscribersMapper subscribersMapper, UserAuthInfoMapper userAuthInfoMapper, ISelfOrderService iSelfOrderService) {
        this.ptSuccessService = ptSuccessService;
        this.ptgoldbeanService = ptgoldbeanService;
        this.redisUtil = redisUtil;
        this.commodityMapper = commodityMapper;
        this.subscribersMapper = subscribersMapper;
        this.userAuthInfoMapper = userAuthInfoMapper;
        this.iSelfOrderService = iSelfOrderService;
    }

    @Override
    public ResponseResult autoInTeam(String userId, String sub1, String goodsId,String teamOrderNo, String orderNo) throws BaseException {
        log.warn("[自动拼团]执行参数:userId={},sub1={},goodsId={},orderNo={}", userId, sub1, goodsId,orderNo);
        PtCurrent ptCurrentSub1 = selectCurrentByUserIdAndOrderNo(sub1, teamOrderNo );
        if (ptCurrentSub1 == null) throw new BaseException(ResponseResultUtils.getResponseResultF("团不存在"));
        //先判断用户是否已经在团内
        boolean existTeam = userId.equals(ptCurrentSub1.getSub1()) || userId.equals(ptCurrentSub1.getSub2()) || userId.equals(ptCurrentSub1.getSub3()) ||userId.equals(ptCurrentSub1.getSub4());
        if (existTeam) throw new BaseException(ResponseResultUtils.getResponseResultF("该用户已经在团内无法参团"));
        //如果用户不在团内,则用户将加入团并且自动创团
        updatePtCurrentSub(ptCurrentSub1, userId, goodsId,orderNo);
        log.warn("[自动拼团]执行成功:userId={},sub1={},goodsId={}", userId, sub1, goodsId);
        return ResponseResultUtils.getResponseResultS("参与拼团成功");
    }

    @Override
    public ResponseResult beginInTeanm(String userId, String goodsId, String orderNo) {
        //判断金豆是否充足
        //ptgoldbeanService.pt(userId,orderNo);
        PtCurrent ptCurrent = this.selectCurrentByUserIdAndOrderNo(userId, orderNo);
        if (ptCurrent != null &&  StringUtils.isEmpty(ptCurrent.getSub4())) throw new BaseException(ResponseResultUtils.getResponseResultF("该用户已经参与拼团该商品"));
        log.warn("[创建拼团] userId={},goodsId={}", userId, goodsId);
        ptCurrent = new PtCurrent(null, userId, null, null, null, goodsId, new Date(), orderNo,null);
        baseMapper.insert(ptCurrent);
        Commodity commodity = commodityMapper.selectById(goodsId);
        redisUtil.set("ptCode:" + ptCurrent.getId(), userId, commodity.getExpirationHour() * 60 * 60);
        return ResponseResultUtils.getResponseResultS("创建拼团成功");
    }

    @Override
    public ResponseResult findTeamByUserIdAndSid(String userId, String sid,String orderNo, Integer pageNo, Integer pageSize) {
        log.warn("[查询拼团] userId={},sid={},pageNo={}，pageSize={}", userId, sid, pageNo, pageSize);
        Page<PtCurrent> page = new Page<>(pageNo, pageSize);
        QueryWrapper<PtCurrent> queryWrapper = new QueryWrapper<PtCurrent>()
                .eq(!StringUtils.isEmpty(userId), "sub1", userId)
                .eq(!StringUtils.isEmpty(sid), "sid", sid)
                .eq(!StringUtils.isEmpty(orderNo), "order_no", orderNo)
                .isNull("sub4");
        IPage<PtCurrent> userIPage = baseMapper.selectPage(page, queryWrapper);
        boolean isSet = setUserImg(userIPage.getRecords(),userId);
        return ResponseResultUtils.getResponseResultDataS(userIPage);
    }

    @Override
    public ResponseResult judgeTeamByUserIdAndSid(String userId, String sid) {
        log.warn("[判断拼团] userId={},sid={}", userId, sid);
        QueryWrapper<PtCurrent> queryWrapper = new QueryWrapper<PtCurrent>()
                .eq("sub1", userId)
                .eq("sid", sid);
        if (!Optional.ofNullable(baseMapper.selectOne(queryWrapper)).isPresent()) {
            return ResponseResultUtils.getResponseResultDataS(false);
        }
        return ResponseResultUtils.getResponseResultDataS(true);
    }

    @Override
    public PtCurrentVo currentToVo(PtCurrent item) {
        PtCurrentVo ptCurrentVo = new PtCurrentVo();
        Integer count = 0;
        if (StringUtils.isEmpty(item.getSub1())) {
            count++;
        }
        if (StringUtils.isEmpty(item.getSub2())) {
            count++;
        }
        if (StringUtils.isEmpty(item.getSub3())) {
            count++;
        }
        if (StringUtils.isEmpty(item.getSub4())) {
            count++;
        }
        ptCurrentVo.setNumber(count);
        Optional.ofNullable(item.getSub1()).ifPresent(x -> {
            Subscribers sub1 = subscribersMapper.selectByPrimaryKey(x);
            ptCurrentVo.setWxPic1(Optional.ofNullable(sub1.getWxpic()).orElse(CommUrls.wx_head_img));
        });
        Optional.ofNullable(item.getSub2()).ifPresent(x -> {
            Subscribers sub2 = subscribersMapper.selectByPrimaryKey(x);
            ptCurrentVo.setWxPic2(Optional.ofNullable(sub2.getWxpic()).orElse(CommUrls.wx_head_img));
        });
        Optional.ofNullable(item.getSub3()).ifPresent(x -> {
            Subscribers sub3 = subscribersMapper.selectByPrimaryKey(x);
            ptCurrentVo.setWxPic3(Optional.ofNullable(sub3.getWxpic()).orElse(CommUrls.wx_head_img));
        });
        Optional.ofNullable(item.getSub4()).ifPresent(x -> {
            Subscribers sub4 = subscribersMapper.selectByPrimaryKey(x);
            ptCurrentVo.setWxPic4(Optional.ofNullable(sub4.getWxpic()).orElse(CommUrls.wx_head_img));
        });
        Long time = Optional.ofNullable(redisUtil.getExpire("ptCode:" + item.getId())).orElse(0L);
        ptCurrentVo.setTimeLast(time.intValue());
        ptCurrentVo.setGoodsId(item.getSid());
        ptCurrentVo.setOrderNo(item.getOrderNo());
        Optional.ofNullable(commodityMapper.selectById(Integer.parseInt(item.getSid()))).ifPresent(x -> {
            ptCurrentVo.setCommodityShowPic(x.getCommodityShowPic());
        });
        return ptCurrentVo;
    }

    @Override
    public PtCurrentVo2 currentToVo2(PtCurrent ptCurrent) {
        PtCurrentVo2 ptCurrentVo2 = new PtCurrentVo2();
        log.warn("[开始组装数据] {}", ptCurrent.toString());
        ptCurrentVo2.setCreateTime(ptCurrent.getCreateTime());
        ptCurrentVo2.setId(ptCurrent.getId());
        ptCurrentVo2.setSid(ptCurrent.getSid());
        Optional.ofNullable(ptCurrent.getSub1()).ifPresent(x -> {
            SubVo subVo = new SubVo();
            PtCurrent ptCurrent1 = selectCurrentByUserIdAndGoodsId(x, ptCurrent.getSid());
            subVo.setCreateTime(DateUtil.dateToStrLong(ptCurrent1.getCreateTime()));
            Subscribers sub1 = Optional.ofNullable(subscribersMapper.selectByPrimaryKey(x)).orElseThrow(() -> new BaseException(ResponseResultUtils.getResponseResultF("用户信息不存在")));
            subVo.setWxPic(Optional.ofNullable(sub1.getWxpic()).orElse(CommUrls.wx_head_img));
            subVo.setMobile(sub1.getMobile());
            Optional.ofNullable(userAuthInfoMapper.findUserAuthInfoById(sub1.getId())).ifPresent(t -> {
                subVo.setUserName(t.getUserRealName());
            });
            ptCurrentVo2.setSub1(subVo);
        });
        Optional.ofNullable(ptCurrent.getSub2()).ifPresent(x -> {
            SubVo subVo = new SubVo();
            PtCurrent ptCurrent1 = selectCurrentByUserIdAndGoodsId(x, ptCurrent.getSid());
            subVo.setCreateTime(DateUtil.dateToStrLong(ptCurrent1.getCreateTime()));
            Subscribers sub = Optional.ofNullable(subscribersMapper.selectByPrimaryKey(x)).orElseThrow(() -> new BaseException(ResponseResultUtils.getResponseResultF("用户信息不存在")));
            subVo.setWxPic(Optional.ofNullable(sub.getWxpic()).orElse(CommUrls.wx_head_img));
            subVo.setMobile(sub.getMobile());
            Optional.ofNullable(userAuthInfoMapper.findUserAuthInfoById(sub.getId())).ifPresent(t -> {
                subVo.setUserName(t.getUserRealName());
            });
            ptCurrentVo2.setSub2(subVo);
        });
        Optional.ofNullable(ptCurrent.getSub3()).ifPresent(x -> {
            SubVo subVo = new SubVo();
            PtCurrent ptCurrent1 = selectCurrentByUserIdAndGoodsId(x, ptCurrent.getSid());
            subVo.setCreateTime(DateUtil.dateToStrLong(ptCurrent1.getCreateTime()));
            Subscribers sub = Optional.ofNullable(subscribersMapper.selectByPrimaryKey(x)).orElseThrow(() -> new BaseException(ResponseResultUtils.getResponseResultF("用户信息不存在")));
            subVo.setWxPic(Optional.ofNullable(sub.getWxpic()).orElse(CommUrls.wx_head_img));
            subVo.setMobile(sub.getMobile());
            Optional.ofNullable(userAuthInfoMapper.findUserAuthInfoById(sub.getId())).ifPresent(t -> {
                subVo.setUserName(t.getUserRealName());
            });
            ptCurrentVo2.setSub3(subVo);
        });
        Optional.ofNullable(ptCurrent.getSub4()).ifPresent(x -> {
            SubVo subVo = new SubVo();
            PtCurrent ptCurrent1 = selectCurrentByUserIdAndGoodsId(x, ptCurrent.getSid());
            subVo.setCreateTime(DateUtil.dateToStrLong(ptCurrent1.getCreateTime()));
            Subscribers sub = Optional.ofNullable(subscribersMapper.selectByPrimaryKey(x)).orElseThrow(() -> new BaseException(ResponseResultUtils.getResponseResultF("用户信息不存在")));
            subVo.setWxPic(Optional.ofNullable(sub.getWxpic()).orElse(CommUrls.wx_head_img));
            subVo.setMobile(sub.getMobile());
            Optional.ofNullable(userAuthInfoMapper.findUserAuthInfoById(sub.getId())).ifPresent(t -> {
                subVo.setUserName(t.getUserRealName());
            });
            ptCurrentVo2.setSub4(subVo);
        });
        ptCurrentVo2.setUserImg(ptCurrent.getUserImg());
        return ptCurrentVo2;
    }

    @Override
    public ResponseResult selectWebList(PtCurrentWebListDTO ptCurrentWebListDTO) {
        String userId = null;
        if (!StringUtils.isEmpty(ptCurrentWebListDTO.getMobile())) {
            Subscribers sub = Optional.ofNullable(subscribersMapper.selectBySubscribers(ptCurrentWebListDTO.getMobile(), null)).orElse(null);
            if (sub != null) {
                userId = sub.getId();
            }
        }

        final String subId = userId;
        final Map<String, Object> data = PageUtils.getDateMapBack(() -> page(PageUtils.getPage(
                new Page<>(), ptCurrentWebListDTO.getOffset(), ptCurrentWebListDTO.getLimit()),
                new QueryWrapper<PtCurrent>()
                        .eq(subId != null, "sub1", subId)
                        .eq(!StringUtils.isEmpty(ptCurrentWebListDTO.getSid()), "sid", ptCurrentWebListDTO.getSid())
                ),
                page -> {
                    List<PtCurrent> lists = page.getRecords();
                    lists.forEach(item -> {
                        item.setSub1(getSubInfo(item.getSub1()));
                        item.setSub2(getSubInfo(item.getSub2()));
                        item.setSub3(getSubInfo(item.getSub3()));
                        item.setSub4(getSubInfo(item.getSub4()));
                        item.setSid(getCommodity(item.getSid()));
                        item.setSuccessTime(getSuccessTime(item.getOrderNo()));
                    });
                    return lists;
                }
        );
        return ResponseResultUtils.getResponseResultDataS(data);
    }

    private Date getSuccessTime(String orderNo) {
        SelfOrder order = iSelfOrderService.getOne(new QueryWrapper<SelfOrder>().eq("order_no", orderNo));
        if (StringUtils.isNull(order)){
            return null;
        }
        return order.getSuccessTime();
    }

    @Override
    public Integer chaTP(String userId, String orderNo) {
      PtCurrent ptCurrent=  selectCurrentByUserIdAndOrderNo(userId,orderNo);
       ptCurrent= Optional.ofNullable(ptCurrent).orElse(new PtCurrent());
        Integer count = 0;
        if (StringUtils.isEmpty(ptCurrent.getSub1())) {
            count++;
        }
        if (StringUtils.isEmpty(ptCurrent.getSub2())) {
            count++;
        }
        if (StringUtils.isEmpty(ptCurrent.getSub3())) {
            count++;
        }
        if (StringUtils.isEmpty(ptCurrent.getSub4())) {
            count++;
        }
        return count;
    }

    private String getCommodity(String sid) {
        Commodity commodity = Optional.ofNullable(commodityMapper.selectById(sid)).orElse(new Commodity());
        return Optional.ofNullable(commodity.getCommodityName()).orElse("未知商品");
    }

    private void updatePtCurrentSub(PtCurrent ptCurrentSub1, String userId, String goodsId,String orderNo) {
        log.warn("[自动拼团] 更新当前状态ptCurrentSub1={},userId={}", ptCurrentSub1.toString(), userId);
        //更新团
        ptCurrentSub1 = Optional.ofNullable(ptCurrentSub1).orElseThrow(() -> new BaseException(ResponseResultUtils.getResponseResultF("参数异常2")));
        if (!StringUtils.isEmpty(ptCurrentSub1.getSub2()) && !StringUtils.isEmpty(ptCurrentSub1.getSub3()) && !StringUtils.isEmpty(ptCurrentSub1.getSub4())) {
            log.warn("[自动拼团] 出现异常,用户拼团全部成功pt={}", ptCurrentSub1);
            throw new BaseException(ResponseResultUtils.getResponseResultF("该团无法参与拼团"));
        }
        if (StringUtils.isEmpty(ptCurrentSub1.getSub2())) {
            //加入一个人则扣除金豆
            //ptgoldbeanService.ptSubGoldBean(ptCurrentSub1.getSub1(),orderNo);
            ptCurrentSub1.setSub2(userId);
            log.warn("[自动拼团] sid={} 更新2号位 userId={}", ptCurrentSub1.getSid(), userId);
        } else if (StringUtils.isEmpty(ptCurrentSub1.getSub3())) {
            ptCurrentSub1.setSub3(userId);
            log.warn("[自动拼团] sid={} 更新3号位 userId={}", ptCurrentSub1.getSid(), userId);
        } else if (StringUtils.isEmpty(ptCurrentSub1.getSub4())) {
            ptCurrentSub1.setSub4(userId);
            log.warn("[自动拼团] sid={} 更新4号位 userId={}", ptCurrentSub1.getSid(), userId);
        }
        baseMapper.updateById(ptCurrentSub1);
        //判断是否出团 若4号位有人存在必然出团
        if (!StringUtils.isEmpty(ptCurrentSub1.getSub4())) {
            log.warn("[自动拼团] sid={} 出团 userId={}", ptCurrentSub1.getSid(), userId);
           // baseMapper.deleteById(ptCurrentSub1.getId()); 删除平团记录
            PtSuccess ptSuccess=new PtSuccess(null, ptCurrentSub1.getSub1(), ptCurrentSub1.getSub2(), ptCurrentSub1.getSub3(), ptCurrentSub1.getSub4(), ptCurrentSub1.getSid(), new Date());
            ptSuccessService.getBaseMapper().insert(ptSuccess);
            iSelfOrderService.partakerSuccess(ptSuccess.getId(), ptCurrentSub1.getOrderNo());
            Boolean b=redisUtil.hasKey("ptCode:" + ptCurrentSub1.getId());
            log.warn("[自动拼团] ptCode:" + ptCurrentSub1.getId()+"成团是否存在key:"+b);
            if (b){
                redisUtil.delete("ptCode:" + ptCurrentSub1.getId());
                log.warn("[自动拼团] 删除Key成功");
            }
            log.warn("[自动拼团] 出团subId={}插入成功记录", ptCurrentSub1.getSub1());
        }
//        //创建团
        PtCurrent ptCurrentNew = new PtCurrent(null, userId, null, null, null, ptCurrentSub1.getSid(), new Date(), orderNo,null);
        baseMapper.insert(ptCurrentNew);
        Commodity commodity = Optional.ofNullable(commodityMapper.selectById(goodsId)).orElseThrow(() -> new BaseException(ResponseResultUtils.getResponseResultF("无法找到店铺")));
        redisUtil.set("ptCode:" + ptCurrentNew.getId(), userId, commodity.getExpirationHour() * 60 * 60);
        log.warn("[自动拼团] 创建拼团 参数={}", ptCurrentNew.toString());
    }

    @Override
    public PtCurrent selectCurrentByUserIdAndGoodsId(String userId, String goodsId) {
        if (StringUtils.isAnyEmpty(userId, goodsId))
            throw new BaseException(ResponseResultUtils.getResponseResultF("参数异常"));

        QueryWrapper<PtCurrent> ptCurrentQueryWrapper =
                new QueryWrapper<PtCurrent>()
                        .eq(!StringUtils.isEmpty(goodsId), "sid", goodsId).eq(!StringUtils.isEmpty(userId), "sub1", userId);
        List<PtCurrent> ptCurrents = baseMapper.selectList(ptCurrentQueryWrapper);
        return ptCurrents.isEmpty()?null:ptCurrents.get(ptCurrents.size()-1);
    }

     @Override
    public PtCurrent selectCurrentByUserIdAndOrderNo(String userId, String orderNo) {
        if (StringUtils.isAnyEmpty(userId, orderNo))
            throw new BaseException(ResponseResultUtils.getResponseResultF("参数异常"));

        QueryWrapper<PtCurrent> ptCurrentQueryWrapper =
                new QueryWrapper<PtCurrent>()
                        .eq(!StringUtils.isEmpty(orderNo), "order_no", orderNo).eq(!StringUtils.isEmpty(userId), "sub1", userId);
        List<PtCurrent> ptCurrents = baseMapper.selectList(ptCurrentQueryWrapper);
        return ptCurrents.isEmpty()?null:ptCurrents.get(ptCurrents.size()-1);
    }

    private String getSubInfo(String userId) {
        if (StringUtils.isEmpty(userId)) return "";
        final String[] result = {"无法查询到用户信息"};
        Optional.ofNullable(subscribersMapper.selectByPrimaryKey(userId)).ifPresent(x -> {
            UserAuthInfo userAuthInfo = Optional.ofNullable(userAuthInfoMapper.findUserAuthInfoById(userId)).orElse(new UserAuthInfo());
            String reultMsg = x.getMobile() + Optional.ofNullable(userAuthInfo.getUserRealName()).orElse("");
            result[0] = reultMsg;
        });
        return result[0];

    }

    private boolean setUserImg(List<PtCurrent> list , String userId){
        if (StringUtils.isNull(list)){
            return false;
        }
        Subscribers subscribers = subscribersMapper.selectsomeByPrimaryKey(userId);
        if (StringUtils.isNull(subscribers)){
            return false;
        }
        list.forEach(item->{item.setUserImg(subscribers.getPic());});
        return true;
    }
}
